/*
 * Copyright (c) 2020 Carnegie Lee
 * All rights reserved
 */
package com.geekc.rediscache.config;

import com.geekc.rediscache.constant.BloomFilterConst;
import com.geekc.rediscache.util.BloomFilterHelper;
import com.google.common.base.Charsets;
import com.google.common.hash.Funnel;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

/**
 * Redis缓存配置类
 * @author Carnegie Lee
 */
@Configuration
public class RedisCacheConfig {

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
        configuration = configuration.serializeKeysWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new StringRedisSerializer()));
        configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));
        return configuration;
    }

    /**
     * 自定义Redis缓存key生成器
     * 使用时需在声明中添加keyGenerator属性
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target /** 目标类 */, Method method /** 目标方法 */, Object... objects /** 入参 */) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getSimpleName());
                sb.append(method.getName());
                for (Object object : objects) {
                    sb.append(object.toString());
                }
                return sb.toString();
            }
        };
    }

    @Bean
    public BloomFilterHelper<String> bloomFilterHelper() {
        BloomFilterHelper<String> bloomFilterHelper = new BloomFilterHelper<String>(
                (Funnel<String>) (from, into) -> into.putString(from, Charsets.UTF_8).putString(from, Charsets.UTF_8),
                BloomFilterConst.BLOOM_FILTER_EXPECTED_INSERTIONS,
                BloomFilterConst.BLOOM_FILTER_FPP);
        return bloomFilterHelper;
    }
}
